// System includes
#include <QDebug>

// Local includes
#include "yigclient.h"
#include "yig.h"


///////////////////
// YigClientThread
//////////////////
YigClientThread::YigClientThread(YigClient* client, int receivePort) :
    mClient(client)
{
    receiveSocket = new UdpReceiveSocket(IpEndpointName( IpEndpointName::ANY_ADDRESS, receivePort));
    //start();
}

YigClientThread::~YigClientThread()
{
    delete receiveSocket;
}

void YigClientThread::run() {
    listener;
    mux.AttachSocketListener(receiveSocket,&listener);
    //mux.RunUntilSigInt();
    mux.Run();
    exec();
}

UdpReceiveSocket* YigClientThread::getReceiveSocket() {
    return receiveSocket;
}

void YigClientThread::quitConnection() {
    mux.DetachSocketListener(receiveSocket, &listener);
    mux.AsynchronousBreak();
    //mux.Break();
}

YigPacketListener* YigClientThread::getPacketListener()
{
    return &listener;
}

void YigClientThread::send(QString address, int port, osc::OutboundPacketStream packet) {
    receiveSocket->SendTo(
            IpEndpointName(
                qPrintable(address),
                port
                ),
            packet.Data(),packet.Size()
        );
}


///////////////
// YigClient
//////////////
YigClient::YigClient(const char *ipAddress, int receivePort, QObject *parent) :
    QObject(parent),
    mIpAddress(ipAddress)
{
    mReceivePort = receivePort;
    oscThread = new YigClientThread(this, receivePort);
    //QObject::connect(&clientThread, SIGNAL(started()), this, SLOT(startNetworking()));
    //QObject::connect(&clientThread, SIGNAL(finished()), this, SLOT(quitNetworking()));

    /*
    // Local socket for transmitting and receiving
    UdpReceiveSocket transmitSocket( IpEndpointName( IpEndpointName::ANY_ADDRESS, 7000 ) );
    // IP address for SCSynth
    IpEndpointName scSynth( "127.0.0.1", 57110 );
    // Binds the transmit socket and listener
    SocketReceiveMultiplexer mux;
    // Our listener class which we extend to parse messages
    TestPacketListener listener;
    // Bind the transmit socket and listener
    mux.AttachSocketListener( &transmitSocket, &listener );

    // Set up our packet:
    int bufferSize = 1024;
    char buffer[bufferSize];
    osc::OutboundPacketStream packet( buffer, bufferSize );

    // Notify SCSynth
    packet << osc::BeginMessage( "/notify" ) << 1 << osc::EndMessage;
    transmitSocket.SendTo( scSynth, packet.Data( ), packet.Size( ) );
    packet.Clear();

    // Get a status update
    packet << osc::BeginMessage( "/status" ) << osc::EndMessage;
    transmitSocket.SendTo( scSynth, packet.Data( ), packet.Size( ) );
    packet.Clear();

    // Run the mux to start listening
    mux.Run();*/
}

YigClient::~YigClient()
{
    if(oscThread->isRunning())
    {
        oscThread->quit();
        oscThread->wait();
    }

    delete oscThread;
}

void YigClient::send(osc::OutboundPacketStream packetStream, int sendPort)
{
    oscThread->send(mIpAddress, sendPort, packetStream);
}

void YigClient::send(QString ip, osc::OutboundPacketStream packetStream, int sendPort)
{
    oscThread->send(ip, sendPort, packetStream);
}

void YigClient::start()
{
    oscThread->start();
}

void YigClient::stop()
{
    oscThread->quitConnection();
    qDebug() << "Yig osc client is shutting down...";
}

void YigClient::setYig(Yig *yig)
{
    mYig = yig;
    yig->setupNetworkConnections(oscThread->getPacketListener());
}
